package org.springframework.samples.mvc.basic.reports.izvrsenarealizacija;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporterParameter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

public abstract class AbstractReportController {

	private static final String REPORT = "report";

	@Autowired
	private DataSource dataSource;

	protected abstract String getEntity();

	protected abstract String getClasspathReportResource();

	protected abstract String getReportTitle();

	@RequestMapping(method = RequestMethod.GET)
	public String getReportInitPage(Model model) {
		model.addAttribute(REPORT, getEntity());
		return "reports/" + getEntity();
	}

	@RequestMapping(value = "report", method = RequestMethod.GET)
	public @ResponseBody
	byte[] getReportInitPage(HttpServletResponse response,
			@RequestParam String dateFrom, @RequestParam String dateTo)
			throws JRException, SQLException, IOException {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		runJasperReport(outputStream, dateFrom, dateTo);
		response.setContentType("application/msword");
		response.setHeader("Content-disposition", "attachment; filename=\""
				+ getReportTitle() + ".docx\"");
		return outputStream.toByteArray();

	}

	private void runJasperReport(OutputStream outputStream, String dateFrom,
			String dateTo) throws JRException, SQLException {
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put("datum_od", dateFrom);
		parameters.put("datum_do", dateTo);
		runJasperReport(outputStream, getClasspathReportResource(), parameters,
				getReportTitle());
	}

	private synchronized void runJasperReport(OutputStream outputStream,
			String reportFile, Map<String, Object> parameters, String naslov)
			throws JRException, SQLException {
		Connection jdbcConnection = dataSource.getConnection();
		try {
			InputStream file = this.getClass().getClassLoader()
					.getResourceAsStream(reportFile);
			if (file == null) {
				throw new RuntimeException("File " + reportFile
						+ " not found on classpath");
			}
			JasperPrint jasperPrint = JasperFillManager.fillReport(file,
					parameters, jdbcConnection);
			System.out.println(jasperPrint.getLocaleCode());
			if (jasperPrint.getPages().size() == 0) {
				System.out.println("EmptyReport");
				return;
			}
			JRDocxExporter jrdocExporter = new JRDocxExporter();
			jrdocExporter.setParameter(JRDocxExporterParameter.OUTPUT_STREAM,
					outputStream);
			jrdocExporter.setParameter(JRExporterParameter.JASPER_PRINT,
					jasperPrint);
			jrdocExporter.exportReport();
		} finally {
			jdbcConnection.close();
		}
	}

}
